home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 001-025 / disk_005 / one.window / one.window.c < prev   
C/C++ Source or Header  |  1992-05-06  |  17KB  |  589 lines

  1. /*
  2.  *
  3.  *    DISCLAIMER:
  4.  *
  5.  *    This program is provided as a service to the programmer
  6.  *    community to demonstrate one or more features of the Amiga
  7.  *    personal computer.  These code samples may be freely used
  8.  *    for commercial or noncommercial purposes.
  9.  * 
  10.  *     Commodore Electronics, Ltd ("Commodore") makes no
  11.  *    warranties, either expressed or implied, with respect
  12.  *    to the program described herein, its quality, performance,
  13.  *    merchantability, or fitness for any particular purpose.
  14.  *    This program is provided "as is" and the entire risk
  15.  *    as to its quality and performance is with the user.
  16.  *    Should the program prove defective following its
  17.  *    purchase, the user (and not the creator of the program,
  18.  *    Commodore, their distributors or their retailers)
  19.  *    assumes the entire cost of all necessary damages.  In 
  20.  *    no event will Commodore be liable for direct, indirect,
  21.  *    incidental or consequential damages resulting from any
  22.  *    defect in the program even if it has been advised of the 
  23.  *    possibility of such damages.  Some laws do not allow
  24.  *    the exclusion or limitation of implied warranties or
  25.  *    liabilities for incidental or consequential damages,
  26.  *    so the above limitation or exclusion may not apply.
  27.  *
  28.  */
  29.  
  30. /* "SIMPLE" demo showing the use of the Intuition windowing system.  
  31.  *
  32.  * Opens a graphics-window, that is also a console window.  When you click
  33.  * in the console window, it echos what you type.  RETURN key issues
  34.  * both a carriage return and a line feed.  When you click in the
  35.  * Graphics window, the console window reports the kinds of events
  36.  * that the graphics window IDCMP is seeing, except, of course for
  37.  * the CLOSEWINDOW gadget that causes a program exit.  Note that a 
  38.  * user will generally have either an IDCMP or a Console attached
  39.  * to a window, but not necessarily both.  (Or if both, then that
  40.  * window won't usually ask for RAWKEYS, to allow the console to 
  41.  * translate them for normal reporting.)
  42.  *
  43.  * No menu stuff is included, but the event handling is included
  44.  * for menu picks within the HandleEvent() function.
  45.  *
  46.  * Additionally, shows how to trap the right hand mouse button
  47.  * events for any given active window.
  48.  *
  49.  * Author:  Rob Peck, 12/18/85
  50.  */
  51.  
  52. /* DEFINES ********************************************************** */
  53.  
  54. #define HOWMUCHTIME 40000
  55.  
  56. #define SECONDS io_Actual
  57. #define MICROSECONDS io_Length
  58.  
  59. #define DEPTH 5
  60. #define WINDOWGADGETS (WINDOWSIZING|WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE)
  61.  
  62. #define INTUITION_MESSAGE (1<<intuitionMsgBit)
  63. #define TYPED_CHARACTER (1<<consoleReadBit)
  64. #define TIME_OUT (1<<timerMsgBit)
  65.  
  66. #define CloseConsole(x) CloseDevice(x)
  67.  
  68. /* INCLUDES ********************************************************** */
  69.  
  70. #include "exec/types.h"
  71. #include "exec/io.h"
  72. #include "exec/memory.h"
  73.  
  74. #include "graphics/gfx.h"
  75. #include "hardware/dmabits.h"
  76. #include "hardware/custom.h"
  77. #include "hardware/blit.h"
  78. #include "graphics/gfxmacros.h"
  79. #include "graphics/copper.h"
  80. #include "graphics/view.h"
  81. #include "graphics/gels.h"
  82. #include "graphics/regions.h"
  83. #include "graphics/clip.h"
  84. #include "exec/exec.h"
  85. #include "graphics/text.h"
  86. #include "graphics/gfxbase.h"
  87.  
  88. #include "devices/console.h"
  89. #include "devices/keymap.h"
  90. #include "devices/timer.h"
  91.  
  92. #include "libraries/dos.h"
  93. #include "graphics/text.h"
  94. #include "libraries/diskfont.h"
  95. #include "intuition/intuition.h"
  96.  
  97. /* EXTERNALS ***************************************************** */
  98.  
  99. extern struct Window *OpenWindow();
  100. extern struct Screen *OpenScreen();
  101. extern struct MsgPort *CreatePort();
  102. extern struct IOStdReq *CreateStdIO();
  103.  
  104. /* GLOBALS ****************************************************** */
  105.  
  106. USHORT class;
  107. USHORT code;
  108. USHORT qualifier;
  109. USHORT mode;        
  110. APTR address;        /* address of the gadget which we hit */
  111. SHORT xx=0;
  112. SHORT yy=0;
  113. SHORT xdir = 2;
  114. SHORT ydir = 0;
  115. SHORT xsize,ysize;
  116.  
  117. long IntuitionBase=0;
  118. long GfxBase=0;
  119.  
  120. struct NewWindow nwGraphics = {
  121.     20, 20,            /* start position        */
  122.     480, 160,         /* width, height         */
  123.     1, 2,            /* detail pen, block pen    */
  124.     GADGETUP | 
  125.     GADGETDOWN | 
  126.     MOUSEBUTTONS | 
  127.     MENUPICK | 
  128.     RAWKEY |      
  129.     /* --------- NOTE ------------------------------------
  130.      
  131.        If you ask for rawkeys for the IDCMP in a window to
  132.        which a console is attached, you will NOT get any
  133.        translated ordinary console keys from the console
  134.        device.  The IDCMP traps all keystrokes, both down
  135.        and up and transmits them to you... console device
  136.        never gets to see any of them.   Complile this
  137.        program with this RAWKEY item commented out and
  138.        you will get ordinary console keys echoed to the
  139.        window.  Otherwise, as it is configured now, you
  140.        get RAW keys only.
  141.  
  142.     ----------------------------------------------------- */ 
  143.     CLOSEWINDOW, 
  144.                 /* IDCMP flags             */
  145.     RMBTRAP | GIMMEZEROZERO | WINDOWGADGETS,
  146.                 /* window flags            */
  147.     NULL,            /* pointer to first user gadget */
  148.     NULL,            /* pointer to user checkmark    */ 
  149.     "Graphics Window",    /* window title     */ 
  150.     NULL,            /* pointer to screen    (later)    */
  151.     NULL,            /* pointer to superbitmap     */
  152.     50,40,200,100,         /* sizing limits min and max */
  153.     WBENCHSCREEN        /* type of screen in which to open */    
  154.     };
  155.  
  156. /* RMBTRAP says that when this window is active, there is no menu to
  157.  * be rendered.... so report all right mouse button transitions to 
  158.  * the user if MOUSEBUTTONS is specified for the IDCMP (and it is) */
  159.  
  160. struct IOStdReq *consoleWriteMsg;       /* I/O request block pointer */
  161. struct MsgPort *consoleWritePort;       /* a port at which to receive */
  162. struct IOStdReq *consoleReadMsg;      /* I/O request block pointer */
  163. struct MsgPort *consoleReadPort;          /* a port at which to receive */
  164.  
  165. char tohex(e) 
  166.     char e;
  167. {
  168.     return( (char)( e < 10 ? (e+'0') : (e-10+'A') ) );
  169. }
  170.  
  171. char topoffset[] = { 0x1b, '[', '7', '4', 'y', '\n', 0 };
  172.     /* NULL-terminated string to send to console to reset scrolling
  173.      * region for the console to 80 lines from the top, leave some
  174.      * room for the graphics rendering */
  175.  
  176. char linesonpage[] = { 0x1b, '[', '8','t', '\n', 0 };
  177.  
  178.  
  179. main()
  180. {
  181.     char letter;        /* one letter at a time from console */
  182.  
  183.     int problem,error;
  184.     int wakeupmask,timerMsgBit;
  185.     
  186.     struct Window *wG;
  187.     struct RastPort *rpG;
  188.     
  189.     struct IntuiMessage *message;    /* the message the IDCMP sends us */
  190.     
  191.     int consoleReadBit, intuitionMsgBit;
  192.         /* integers that represent the signal bit assigned for the
  193.           * console and for intuition's IDCMP on which one waits 
  194.           * for some input during a Wait() function call */
  195.  
  196.     struct MsgPort *timerport;              /* for timer communications */
  197.     struct IOStdReq *timermsg;              /* for timer */
  198.  
  199.     GfxBase = OpenLibrary("graphics.library", 0);
  200.     if (GfxBase == NULL)
  201.     {
  202.         printf("Unable to open graphics library\n");
  203.         goto cleanup1;
  204.     }
  205.     IntuitionBase = OpenLibrary("intuition.library", 0);
  206.     if (IntuitionBase == NULL)
  207.     {
  208.         printf("Unable to open intuition library\n");
  209.         goto cleanup1;
  210.     }
  211.  
  212.         timerport = CreatePort(0,0);
  213.         if (timerport == 0) goto cleanup1;
  214.         timermsg = CreateStdIO(timerport);
  215.         if (timermsg == 0) goto cleanup1a;
  216.  
  217.     wG = OpenWindow(&nwGraphics);    /* open a window for graphics*/
  218.     if ( wG == NULL )
  219.     {
  220.         printf ("\nCouldnt open a window");
  221.         goto cleanup2;
  222.     }
  223.  
  224.     rpG = wG->RPort;    /* set a rastport pointer for both windows */
  225.  
  226.     /* create ports and messages for communicating with the console */
  227.  
  228.         consoleWritePort = CreatePort("my.con.write",0);
  229.         if(consoleWritePort == 0)
  230.                 { problem = 5; goto cleanup5; }
  231.         consoleWriteMsg =  CreateStdIO(consoleWritePort);
  232.         if(consoleWritePort == 0)
  233.                 { problem = 6; goto cleanup6; }
  234.  
  235.         consoleReadPort = CreatePort("my.con.read",0);
  236.         if(consoleReadPort == 0)
  237.                 { problem = 7; goto cleanup7; }
  238.         consoleReadMsg =  CreateStdIO(consoleReadPort);
  239.         if(consoleReadPort == 0)
  240.                 { problem = 8; goto cleanup8; }
  241.  
  242.     /* now attach a console to the window provided for its use */
  243.  
  244.         error = OpenConsole(consoleWriteMsg,consoleReadMsg,wG);
  245.         if(error != 0)
  246.                 { problem = 10; goto cleanup10; }
  247.                 /* attach a console to this window, initialize
  248.                  * for both write and read */
  249.  
  250.     /* Initialize the timer */
  251.         if (init_timer(timermsg) != 0) goto cleanup10;
  252.  
  253.     /* ask for the first timing interval */
  254.     /* 40,000 microseconds = .04 sec */
  255.     set_timer(timermsg,0,HOWMUCHTIME);
  256.  
  257.     /* tell console where to put a character that 
  258.      * it wants to give me queue up first read */
  259.  
  260.         QueueRead(consoleReadMsg,&letter); 
  261.  
  262.     /* reset the top offset to leave room for graphics */
  263.     ConPutStr(consoleWriteMsg,&topoffset[0]);
  264.     /* reset the number of lines on the page for text */
  265.     ConPutStr(consoleWriteMsg,&linesonpage[0]);
  266.  
  267.         ConWrite(consoleWriteMsg,"\fHello, World\r\n",15);
  268.  
  269.     ConWrite(consoleWriteMsg,"I will echo what\r\n you type\r\n",-1);
  270.     /* (use the variable length ... -1 ... function of ConWrite) */
  271.  
  272.     ConWrite(consoleWriteMsg,"Hit close gadget\r\n to exit",-1);
  273.     
  274. /* find out which signals to wait for.... Intuition allocates a signal bit
  275.  * for an IDCMP and the call to OpenConsole allocates a different bit */
  276.  
  277.     consoleReadBit = consoleReadPort->mp_SigBit;
  278.     intuitionMsgBit = wG->UserPort->mp_SigBit;
  279.     timerMsgBit = timerport->mp_SigBit;
  280.  
  281. /* this code assumes that the only events we expect to wake up for are
  282.  * characters typed to the console or messages from intuition arriving at
  283.  * the IDCMP */
  284.  
  285. /*  Wait for a CLOSEWINDOW or other event from intuition as well as
  286.  *  waiting for a typed character */
  287.  
  288.     do 
  289.     {
  290.         wakeupmask = Wait( INTUITION_MESSAGE | 
  291.                   TYPED_CHARACTER |
  292.                   TIME_OUT );
  293.  
  294.         /* if an intuition message, copy the contents of the
  295.          * message to some global variables (our own local 
  296.          * copy of the message) and reply immediately */
  297.  
  298.         if(wakeupmask & INTUITION_MESSAGE)
  299.         {
  300.             while( (message = (struct IntuiMessage *)
  301.                  GetMsg(wG->UserPort) ) != NULL)
  302.             {
  303.                 /* EMPTY THE PORT!!!! */
  304.                 /* make a local copy of the 
  305.                  * message before replying, and
  306.                  * then try to handle the event */
  307.                 class = message->Class;
  308.                 code =  message->Code;
  309.                 qualifier = message->Qualifier;
  310.                 address = message->IAddress;
  311.                 ReplyMsg(message);
  312.                 if(HandleEvent() == FALSE) break;
  313.             }
  314.         }
  315.          if(wakeupmask & TYPED_CHARACTER)
  316.         {
  317.             /* Task woke up because a message arrived
  318.              * at this port, so we must remove the 
  319.              * message from the port to allow its reuse 
  320.              */
  321.             GetMsg(consoleReadPort);
  322.  
  323.             /* Console character was read into 'letter'
  324.              */
  325.             ConPutChar(consoleWriteMsg,letter);
  326.             if(letter == '\r')
  327.                 ConPutChar(consoleWriteMsg,'\n');
  328.             /* added a line feed to a carriage return */
  329.  
  330.             /* Now that have typed the character, must
  331.              * send off another read request 
  332.              */ 
  333.             QueueRead(consoleReadMsg, &letter);
  334.         }
  335.          if(wakeupmask & TIME_OUT)
  336.         {
  337.             /* Task woke up because of a timeout;  that 
  338.              * is, the timer completed and returned its
  339.              * message to the reply port */
  340.             GetMsg(timerport);
  341.         
  342.             drawSomething(wG);
  343.             set_timer(timermsg,0,HOWMUCHTIME);    
  344.         }
  345.      
  346.     } while (HandleEvent());    /* keep going as long as 
  347.                          * HandleEvent returns nonzero */
  348.     problem = 0;
  349.  
  350.     AbortIO(consoleReadMsg);    /* cancel the last queued read */
  351.  
  352.         CloseConsole(consoleWriteMsg);
  353.  
  354.    cleanup10:
  355.    cleanup8:
  356.         DeleteStdIO(consoleReadMsg);
  357.    cleanup7:
  358.         DeletePort(consoleReadPort);
  359.    cleanup6:
  360.         DeleteStdIO(consoleWriteMsg);
  361.    cleanup5:
  362.         DeletePort(consoleWritePort);
  363.    cleanup3:
  364.     CloseWindow(wG);
  365.    cleanup2:
  366.     if (GfxBase != NULL) CloseLibrary(GfxBase);
  367.  
  368.     AbortIO(timermsg);
  369.  
  370.     DeleteStdIO(timermsg);
  371.    cleanup1a:
  372.     DeletePort(timerport);
  373.    cleanup1:
  374.         if (IntuitionBase != NULL) CloseLibrary(IntuitionBase);
  375.         if(problem > 0) 
  376.         exit(problem+1000);
  377.     else
  378.         return(0);
  379. }
  380.  
  381. drawSomething(w)
  382. struct Window *w;
  383. {
  384.     struct RastPort *rp;
  385.     SHORT xsize, ysize;
  386.     rp = w->RPort;
  387.     xsize = w->Width;    /* use current size limits for the window */
  388.     ysize = (w->Height)/2;  /* draw only in top half of window */
  389.     SetAPen(rp,RangeRand(4));    /* can even draw in background color */
  390.     Move(rp, RangeRand(xsize), RangeRand(ysize));
  391.     Draw(rp, RangeRand(xsize), RangeRand(ysize));
  392.     return(0);
  393. }
  394.  
  395. HandleEvent()
  396. {
  397.     switch(class) 
  398.     {
  399.         case CLOSEWINDOW:
  400.             return(FALSE);    /* cleanup and exit if close
  401.                      * gadget is hit */
  402.             break;
  403.         /* could have provided processing for each of these */
  404.         case RAWKEY:
  405.                         ConPutStr(consoleWriteMsg,"\n\rRAWKEY event:\n\r");
  406.                         ConPutStr(consoleWriteMsg,"value = ");
  407.                         ConPutChar(consoleWriteMsg,
  408.                                         (tohex((code & 0xf0)>>4)));
  409.                         ConPutChar(consoleWriteMsg,(tohex(code & 0x0f)));
  410.                         break;
  411.         case GADGETUP:
  412.             break;    /* event not in use */
  413.         case GADGETDOWN:
  414.             break;    /* event not in use */
  415.         case MOUSEBUTTONS:
  416.              ConPutStr(consoleWriteMsg,"\n\rMOUSEBUTTONS event=");
  417.              switch(code)
  418.              {
  419.             case SELECTDOWN:
  420.                   ConPutStr(consoleWriteMsg,"\n\rSELECTDOWN\n\r");
  421.                 break;
  422.             case SELECTUP:
  423.                   ConPutStr(consoleWriteMsg,"\n\rSELECTUP\n\r");
  424.                 break;
  425.             case MENUDOWN:
  426.                   ConPutStr(consoleWriteMsg,
  427.                     "\n\rMENUDOWN\n\r");
  428.                 break;
  429.             case MENUUP:
  430.                   ConPutStr(consoleWriteMsg,
  431.                     "\n\rMENUUP\n\r");
  432.                 break;
  433.              }
  434.     }
  435.     class = 0; code = 0; qualifier = 0; address = 0;
  436.     return(TRUE);
  437. }
  438.  
  439.  
  440. /* These functions are taken directly from the console.device chapter
  441.  * in the Amiga V1.1 ROM KERNEL manual. */
  442.  
  443.  
  444. /* Open a console device */
  445.  
  446.     /* this function returns a value of 0 if the console 
  447.      * device opened correctly and a nonzero value (the error
  448.      * returned from OpenDevice) if there was an error.
  449.      */
  450.     
  451.     int
  452. OpenConsole(writerequest,readrequest,window)
  453.     struct IOStdReq *writerequest;
  454.     struct IOStdReq *readrequest;
  455.     struct Window *window;
  456.     {    
  457.         int error;    
  458.             writerequest->io_Data = (APTR) window;
  459.             writerequest->io_Length = sizeof(*window);
  460.             error = OpenDevice("console.device", 0, writerequest, 0);
  461.         readrequest->io_Device = writerequest->io_Device;
  462.         readrequest->io_Unit   = writerequest->io_Unit;
  463.             /* clone required parts of the request */
  464.         return(error);    
  465.     }
  466.  
  467. /* Output a single character to a specified console */ 
  468.  
  469.     int
  470. ConPutChar(request,character)
  471.     struct IOStdReq *request;
  472.     char character;
  473.     {
  474.             request->io_Command = CMD_WRITE;
  475.             request->io_Data = (APTR)&character;
  476.             request->io_Length = 1;
  477.             DoIO(request);
  478.         /* command works because DoIO blocks until command is
  479.          * done (otherwise pointer to the character could become
  480.          * invalid in the meantime).
  481.          */
  482.         return(0);
  483.     }
  484.  
  485. /* Output a stream of known length to a console */ 
  486.  
  487.     int
  488. ConWrite(request,string,length)
  489.     struct IOStdReq *request;
  490.     char *string;
  491.     int length;
  492.     {
  493.             request->io_Command = CMD_WRITE;
  494.             request->io_Data = (APTR)string;
  495.             request->io_Length = length; 
  496.             DoIO(request);
  497.         /* command works because DoIO blocks until command is
  498.          * done (otherwise pointer to string could become
  499.          * invalid in the meantime).
  500.          */
  501.         return(0);
  502.     }
  503.  
  504. /* Output a NULL-terminated string of characters to a console */ 
  505.  
  506.     int
  507. ConPutStr(request,string)
  508.     struct IOStdReq *request;
  509.     char *string;
  510.     {
  511.             request->io_Command = CMD_WRITE;
  512.             request->io_Data = (APTR)string;
  513.             request->io_Length = -1;  /* tells console to end when it
  514.                        * sees a terminating zero on
  515.                        * the string. */
  516.             DoIO(request);
  517.         return(0);
  518.     }
  519.     
  520.     /* queue up a read request to a console, show where to
  521.      * put the character when ready to be returned.  Most
  522.      * efficient if this is called right after console is
  523.      * opened */
  524.  
  525.     int
  526. QueueRead(request,whereto)
  527.     struct IOStdReq *request;
  528.     char *whereto;
  529.     {
  530.             request->io_Command = CMD_READ;
  531.             request->io_Data = (APTR)whereto;
  532.             request->io_Length = 1;
  533.             SendIO(request);
  534.         return(0);
  535.     }
  536.  
  537.     /* see if there is a character to read.  If none, don't wait, 
  538.      * come back with a value of -1 */
  539.  
  540.     int 
  541. ConMayGetChar(request,requestPort, whereto)
  542.     struct IOStdReq *request;
  543.     char *whereto;
  544.     {
  545.             register temp;
  546.  
  547.             if ( GetMsg(requestPort) == NULL ) return(-1);
  548.             temp = *whereto;
  549.             QueueRead(request,whereto);
  550.             return(temp);
  551.     }
  552.  
  553.     /* go and get a character; put the task to sleep if
  554.      * there isn't one present */
  555.  
  556.     UBYTE
  557. ConGetChar(consolePort,request,whereto)
  558.     struct IOStdReq *request; 
  559.     struct MsgPort *consolePort;   
  560.         char *whereto;
  561.     {
  562.         register UBYTE temp;
  563.         while((GetMsg(consolePort) == NULL)) WaitPort(consolePort);
  564.         temp = *whereto;    /* get the character */
  565.         QueueRead(request,whereto);
  566.         return(temp);
  567.     }
  568.             
  569. int 
  570. init_timer(tmsg)    /* return an error code if timer did not open */
  571. {
  572.         return( OpenDevice(TIMERNAME,UNIT_VBLANK,tmsg,0));
  573. }
  574.  
  575.  
  576. int
  577. set_timer(tmsg,sec,micro)
  578. ULONG sec,micro;
  579. struct IOStdReq *tmsg;
  580. {
  581.         tmsg->io_Command = TR_ADDREQUEST;    /* add a new timer request */
  582.         tmsg->SECONDS = sec;        /* seconds */
  583.         tmsg->MICROSECONDS = micro; /* microseconds */
  584.         SendIO( tmsg );             /* post a request to the timer */
  585.         return(0);
  586. }
  587.  
  588.  
  589.